home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Gold Collection
/
Software Vault - The Gold Collection (American Databankers) (1993).ISO
/
cdr25
/
21cid.zip
/
CASPREP.CMD
next >
Wrap
OS/2 REXX Batch file
|
1993-01-28
|
94KB
|
1,843 lines
/********************************************************************/
/* This exec will merge the base and user created pieces of the */
/* LCU.CMD file into the final .CMD file. */
/* */
/* This exec reads into a stem variable a user defined input file */
/* and a base file. These 2 files are merged into an output file */
/* which is a command file used by LCU to install products on a */
/* client machine. */
/* */
/* The user defined file is read from the stem variable that it is */
/* contained in and each line is parsed to get the information */
/* needed to build the output file. 2 types of input files are */
/* handled by this exec; the basic and the advanced input files. */
/* These are defined in the LCU user's guide. */
/* */
/* Following are the structures that are used when parsing the */
/* input file and building the output file: */
/* */
/* - prod_cnt - util_cnt - elem_cnt - vars_cnt */
/*| | | | */
/*| | | | */
/*| Product | Utility | Queue | Vars */
/*V --------- V --------- V --------- V --------- */
/* |prog.name| |prog.name| |Prod 1 | 1|Var 1 | */
/*P|---------| U|---------| e|---------| |---------| */
/*r|user_name| t|user_name| l|Prod 2 | 2|Var 2 | */
/*o|---------| i|---------| e|---------| |---------| */
/*d|invoke | l|invoke | m|Prod 3 | 3|Var 3 | */
/* |---------| |---------| |---------| |---------| */
/*1|rspdir | 1|rspdir | 1|Prod 4 | 4|Var 4 | */
/* |---------| |---------| |---------| |---------| */
/* |default | |default | |Srvattch | / / */
/* |---------| |---------| |---------| / / */
/* / / / / / / n|Var n | */
/* / / / / / / |---------| */
/* |prog.name| |prog.name| |Prod 1 | */
/*p|---------| U|---------| e|---------| */
/*r|user_name| t|user_name| l|Prod 2 | */
/*o|---------| i|---------| e|---------| */
/*d|invoke | l|invoke | m|Prod 3 | */
/* |---------| |---------| |---------| */
/*n|rspdir | n|rspdir | n|Srvattch | */
/* |---------| |---------| --------- */
/* |default | |default | */
/* --------- --------- */
/* */
/* */
/********************************************************************/
/* */
/* Internal Subroutines */
/* */
/********************************************************************/
/* */
/* */
/* fix_quotes: procedure */
/* remove_comments: procedure */
/* bump_inc: procedure */
/* help: procedure */
/* */
/********************************************************************/
/********************************************************************/
/* */
/* Parse the input parameters - The user can specify the user */
/* defined file, the output file, and the base file to be used */
/* by the preprocessor. */
/* */
/********************************************************************/
parse upper value arg(1) with infn '.' infext outfn '.' outfext basefn '.' basefext
/********************************************************************/
/* */
/* Fill in the defaults if variables are blank */
/* */
/********************************************************************/
if infn = '' | infn = '?' then /* If the input file name */
do /* is blank or ? then */
call help /* call help */
return (1)
end
if outfn = '' then /* If the output file */
do /* name is blank then */
call help /* call help */
return (1)
end
if basefn = '' then basefn = 'CASBASE' /* Base file name */
if basefext = '' then basefext = 'FIL' /* Base file type */
/********************************************************************/
/* */
/* Get the base part of the LCU.CMD file and store in an stem */
/* */
/********************************************************************/
inputfile = basefn||'.'||basefext
line_ctr = 1
/********************************************************************/
/* */
/* See if the base file exists. If not display error. */
/* */
/********************************************************************/
if stream(inputfile,'c','query exists') <> '' then
do while lines(inputfile) > 0
base_cmd.data.line_ctr = linein(inputfile)
line_ctr = line_ctr + 1
end
else do
say "Error - Base file " inputfile " not found."
return (1)
end
base_cmd.data.0 = line_ctr - 1
/********************************************************************/
/* */
/* Get the user part of the LCU.CMD file and store in an array */
/* */
/********************************************************************/
inputfile = infn||'.'||infext
say "Reading input file " infn||'.'infext
line_ctr = 1
/********************************************************************/
/* */
/* See if the input file exists. If not display error. */
/* */
/********************************************************************/
if stream(inputfile,'c','query exists') <> '' then
do while lines(inputfile) > 0
client_cmd.data.line_ctr = linein(inputfile)
line_ctr = line_ctr + 1
end
else do
say "Error - Input file " inputfile " not found."
return (1)
end
client_cmd.data.0 = line_ctr - 1
say 'Processing' inputfile
/********************************************************************/
/* */
/* Start reading the client CMD file, parse the data and update */
/* the appropriate variables. */
/* */
/********************************************************************/
var_cnt = 1 /* Variable counter */
prod_cnt=1 /* product counter */
util_cnt=1 /* utility counter */
srvatt_cnt=1 /* SRVATTACH counter */
queue_cnt = 1 /* Queue counter */
element = 1 /* Queue element counter */
user_cnt = 1 /* user line counter */
name_inc = 1 /* used to create a unique name */
srvattch_cnt = 1 /* srvattch counter */
que_srvattch_cnt = 1 /* install queue srvattch counter */
TRUE = 1 /* true constant */
FALSE = 0 /* false constant */
NOPLUS = FALSE /* no plus found flag */
/********************************************************************/
/* */
/* Process each line of the user defined file. Remove any comments */
/* and search for keywords. */
/* */
/********************************************************************/
do client_i = 1 to client_cmd.data.0
client_cmd.data.client_i = remove_comments(client_cmd.data.client_i)
keyword_id = pos(':',strip(client_cmd.data.client_i))
if keyword_id = 1 then do
parse value client_cmd.data.client_i with keyword arg1
select
/********************************************************************/
/* */
/* Process :VARS keyword */
/* Remove any comments parse the line into the variable and the */
/* variable assignment. Fix the quotes to not be around any */
/* variables. Store the variable away until the final file is built.*/
/* Add the configsys variable which is needed in every output file. */
/* */
/********************************************************************/
when translate(keyword) = ':VARS'
then do
call bump_inc
do while translate(client_cmd.data.client_i) <> ":ENDVARS"
/* call remove_comments(client_cmd.data.client_i) */
vars.var_cnt = client_cmd.data.client_i
parse var client_cmd.data.client_i variable '=' assignment
variable = strip(variable)
if translate(variable) = "EXEPATH" then
exepath_done = 1
if translate(variable) = "BOOTDRIVE" then
bootdrive_done = 1
assignment = strip(assignment)
assignment = fix_quotes(assignment)
vars.var_cnt = variable '=' assignment
call bump_inc
if client_cmd.data.client_i = '' then call bump_inc
var_cnt = var_cnt + 1
end
vars.var_cnt = "configsys = bootdrive || ""\CONFIG.SYS"""
if bootdrive_done <> 1
then do
say "Error - BOOTDRIVE variable not defined."
end
if exepath_done <> 1
then do
say "Error - EXEPATH variable not defined."
end
if exepath_done <> 1 | bootdrive_done <> 1
then return (1)
end
/********************************************************************/
/* */
/* Process :SRVATTCH keyword */
/* Remove any comments. Fix the quotes to not be around any */
/* variables. Store the SRVATTCH away until the final file is built.*/
/* */
/********************************************************************/
when translate(keyword) = ':SRVATTCH'
then do
call bump_inc
do while translate(client_cmd.data.client_i) <> ":ENDSRVATTCH"
/* call remove_comments(client_cmd.data.client_i) */
srvattch.srvatt_cnt = client_cmd.data.client_i
srvattch.srvatt_cnt = fix_quotes(srvattch.srvatt_cnt)
srvatt_cnt = srvatt_cnt + 1
call bump_inc
if client_cmd.data.client_i = '' then call bump_inc
end
end
/********************************************************************/
/* */
/* Process :PROG keyword */
/* Parse the line to get the keyword and the argument. Remove */
/* any blanks around the keyword and the argument. Processing */
/* continues until :ENDPROG is found. */
/* */
/********************************************************************/
when translate(keyword) = ':PROG'
then do
if symbol('prog_name.arg1') = 'LIT'
then do
product.prod_cnt.prog_name = arg1
call bump_inc
prog_name.arg1 = arg1
end
else do
say "Error - Duplicate Prog name was found ("arg1") line number " client_i
return (1)
end
do while translate(client_cmd.data.client_i) <> ":ENDPROG"
parse value client_cmd.data.client_i with keyword '=' arg1
keyword=strip(keyword)
arg1=strip(arg1)
select
/********************************************************************/
/* */
/* Process :NAME keyword */
/* Check to see if this name has been used before. If yes, tell the */
/* user this is a duplicate name. If no, store it away in the part */
/* of the product array for this product. Also, put it in the names */
/* array so we know it has been used. Display message if duplicate */
/* name is found. */
/* */
/********************************************************************/
when translate(keyword) = 'NAME'
then do
if symbol('names.arg1') = 'LIT'
then do
product.prod_cnt.name = arg1
call bump_inc
names.arg1 = arg1
end
else do
say "Error - Duplicate Product name was found ("arg1") line number " client_i
return (1)
end
end
/********************************************************************/
/* */
/* Process :INVOKE keyword */
/* Fix the quotes around any variables. Check to see if the argument*/
/* spans more than 1 line. If yes, process the lines until next */
/* keyword. Store it away in the part of the product array for this */
/* product. The Invoke keyword may span more than one line so each */
/* line is store in a seperate element of the invoke array. */
/* invoke_cnt is the count of the invoke array. Each element in the */
/* array has the leading and traing blanks removed and has the */
/* quotes changed from denoting the variable (input file form) */
/* to denoting the string (REXX form). */
/* */
/********************************************************************/
when translate(keyword) = 'INVOKE'
then do
product.prod_cnt.invoke.1 = arg1
product.prod_cnt.invoke.1 = fix_quotes(product.prod_cnt.invoke.1)
invoke_cnt = 2
call bump_inc
call find_keyword
do while result <> 1 &,
substr(strip(client_cmd.data.client_i),1,1) <> ":"
product.prod_cnt.invoke.invoke_cnt = strip(client_cmd.data.client_i)
product.prod_cnt.invoke.invoke_cnt = fix_quotes(product.prod_cnt.invoke.invoke_cnt)
invoke_cnt = invoke_cnt + 1
call bump_inc
if client_cmd.data.client_i = ''
then do
call bump_inc
call find_keyword
end
else do
call find_keyword
end
end
end
/********************************************************************/
/* */
/* Process :RSPDIR keyword */
/* Fix the quotes around any variables. Store it away in the part */
/* of the product array for this product. */
/* */
/********************************************************************/
when translate(keyword) = 'RSPDIR'
then do
if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
then do
arg1 = fix_quotes(arg1)
product.prod_cnt.rspdir = arg1
call bump_inc
end
else call bump_inc
end
/********************************************************************/
/* */
/* Process :DEFAULT keyword */
/* Fix the quotes around any variables. Store it away in the part */
/* of the product array for this product. */
/* */
/********************************************************************/
when translate(keyword) = 'DEFAULT'
then do
if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
then do
arg1 = fix_quotes(arg1)
product.prod_cnt.default = arg1
call bump_inc
end
else call bump_inc
end
/********************************************************************/
/* */
/* If this line is blank skip over it. */
/* */
/********************************************************************/
when translate(keyword) = ''
then do
call bump_inc
end
/********************************************************************/
/* */
/* If the keyword is invalid tell the user. */
/* */
/********************************************************************/
otherwise
say "Error - Found invalid keyword in :PROG list ("keyword") line number" client_i
return (1)
end
end
/********************************************************************/
/* */
/* This product is complete so start a new product definition. */
/* */
/********************************************************************/
prod_cnt = prod_cnt + 1
end
/********************************************************************/
/* */
/* Process :UTILITY keyword */
/* Parse the line to get the keyword and the argument. Remove */
/* any blanks around the keyword and the argument. Processing */
/* continues until :ENDUTILITY is found. */
/* */
/********************************************************************/
when translate(keyword) = ':UTILITY'
then do
if symbol('prog_name.arg1') = 'LIT'
then do
utility.util_cnt.util_name = arg1
call bump_inc
prog_name.arg1 = arg1
end
else do
say "Error - Duplicate Utility name was found ("arg1") line number " client_i
return (1)
end
do while translate(client_cmd.data.client_i) <> ":ENDUTILITY"
parse value client_cmd.data.client_i with keyword '=' arg1
keyword = strip(keyword)
arg1 = strip(arg1)
select
/********************************************************************/
/* */
/* Process :NAME keyword */
/* Check to see if this name has been used before. If yes, tell the */
/* user this is a duplicate name. If no, store it away in the part */
/* of the utility array for this utility. Also, put it in the names */
/* array so we know it has been used. Display message if duplicate */
/* name is found. */
/* */
/********************************************************************/
when translate(keyword) = 'NAME'
then do
if symbol('names.arg1') = 'LIT'
then do
utility.util_cnt.name = arg1
call bump_inc
names.arg1 = arg1
end
else do
say "Error - Duplicate Utility name was found ("arg1") line number " client_i
return (1)
end
end
/********************************************************************/
/* */
/* Process :INVOKE keyword */
/* Fix the quotes around any variables. Check to see if the argument*/
/* spans more than 1 line. If yes, process the lines until next */
/* keyword. Store it away in the part of the utility array for this */
/* utility. The Invoke keyword may span more than one line so each */
/* line is store in a seperate element of the invoke array. */
/* invoke_cnt is the count of the invoke array. Each element in the */
/* array has the leading and traing blanks removed and has the */
/* quotes changed from denoting the variable (input file form) */
/* to denoting the string (REXX form). */
/* */
/********************************************************************/
when translate(keyword) = 'INVOKE'
then do
utility.util_cnt.invoke.1 = arg1
utility.util_cnt.invoke.1 = fix_quotes(utility.util_cnt.invoke.1)
invoke_cnt = 2
call bump_inc
call find_keyword
do while result <> 1 &,
substr(strip(client_cmd.data.client_i),1,1) <> ":"
utility.util_cnt.invoke.invoke_cnt = strip(client_cmd.data.client_i)
utility.util_cnt.invoke.invoke_cnt = fix_quotes(utility.util_cnt.invoke.invoke_cnt)
invoke_cnt = invoke_cnt + 1
call bump_inc
if client_cmd.data.client_i = ''
then do
call bump_inc
call find_keyword
end
else do
call find_keyword
end
end
end
/********************************************************************/
/* */
/* Process :RSPDIR keyword */
/* Fix the quotes around any variables. Store it away in the part */
/* of the utility array for this utility. */
/* */
/********************************************************************/
when translate(keyword) = 'RSPDIR'
then do
if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
then do
arg1 = fix_quotes(arg1)
utility.util_cnt.rspdir = arg1
call bump_inc
end
else call bump_inc
end
/********************************************************************/
/* */
/* Process :DEFAULT keyword */
/* Fix the quotes around any variables. Store it away in the part */
/* of the utility array for this utility. */
/* */
/********************************************************************/
when translate(keyword) = 'DEFAULT'
then do
if strip(arg1,b,'"') <> "" & strip(arg1,b,"'") <> ""
then do
arg1 = fix_quotes(arg1)
utility.util_cnt.default = arg1
call bump_inc
end
else call bump_inc
end
/********************************************************************/
/* */
/* If this line is blank skip over it. */
/* */
/********************************************************************/
when translate(keyword) = ''
then do
call bump_inc
end
/********************************************************************/
/* */
/* If the keyword is invalid tell the user. */
/* */
/********************************************************************/
otherwise do
say "Error - Found invalid keyword in :UTILITY list ("keyword") line number " client_i
return (1)
end /* end otherwise */
end /* end select */
end /* end do while */
/********************************************************************/
/* */
/* This utility is complete so start a new utility definition. */
/* */
/********************************************************************/
util_cnt = util_cnt + 1
end /* end do for utility */
/********************************************************************/
/* */
/* Process :INSTALL keyword */
/* There are 2 types of installs. The first has KEYWORDS as a */
/* parameter. It is used in the advanced form of input file. The */
/* second type does not have any parameters. It is used for the */
/* basic input file. Processing for both continues until :ENDINSTALL*/
/* is found. */
/* */
/********************************************************************/
when translate(keyword) = ':INSTALL'
then do
start_pars = 1
/********************************************************************/
/* */
/* Process :INSTALL KEYWORDS */
/* */
/* Process until :ENDINSTALL is found. Parse the line into keyword */
/* and arg1. Strip leading and trailing blanks from the keyword and */
/* arg1. */
/* */
/********************************************************************/
if translate(arg1) = 'KEYWORDS'
then do
call bump_inc
do while translate(client_cmd.data.client_i) <> ":ENDINSTALL"
parse value client_cmd.data.client_i with,
keyword '=' arg1
keyword = strip(keyword)
arg1 = strip(arg1)
select
/********************************************************************/
/* */
/* The following code processes a SRVATTCH=. A SRVATTCH= will */
/* insert a SRVATTCH statement in a "When OVERALL STATE" sequence. */
/* It will not be placed in a runinstall statement. It will be */
/* place in the CMD file just as it is in the advanced text */
/* file; quotes will not be adjusted. */
/* */
/********************************************************************/
when translate(keyword) = 'SRVATTCH'
then do
queue.queue_cnt.element = client_cmd.data.client_i
nextline = client_i + 1
if pos('+', client_cmd.data.nextline) = 0 then do
queue_cnt= queue_cnt + 1
element = 1
end
else element = element + 1
call bump_inc
end
/********************************************************************/
/* */
/* The following code processes a USERLINE=. A USERLINE= will */
/* insert a line in a "When OVERALL STATE" sequence. It will not */
/* be placed in a runinstall statement. It will be place in the */
/* CMD file just as it is in the advanced text file; quotes will */
/* not be adjusted. */
/* */
/********************************************************************/
when translate(keyword) = 'USERLINE'
then do
queue.queue_cnt.element = client_cmd.data.client_i
nextline = client_i + 1
if pos('+', client_cmd.data.nextline) = 0
then do
queue_cnt= queue_cnt + 1
element = 1
end
else element = element + 1
call bump_inc
end
otherwise do
/********************************************************************/
/* */
/* The following code will parse the program install statements. */
/* */
/********************************************************************/
do until NOPLUS = TRUE
select
when client_cmd.data.client_i = "" then
call bump_inc
/********************************************************************/
/* */
/* The following code will look for any statements that end in a +. */
/* If the statement is only a plus bump to the next line in the */
/* CMD file. Or else take off any leading and trailing +s and */
/* parse the string. Put the product names in the queue to be */
/* processed later. */
/* */
/********************************************************************/
when lastpos('+', strip(client_cmd.data.client_i)) =,
length(strip(client_cmd.data.client_i)) then do
if substr(strip(client_cmd.data.client_i),1) = '+' &,
length(strip(client_cmd.data.client_i)) = 1
then call bump_inc
else do
client_data = strip(strip(client_cmd.data.client_i),'L','+')
client_data = strip(client_data,'T','+')
last_plus = lastpos('+', client_data)
if last_plus = 0 then do
queue.queue_cnt.element = client_data
call bump_inc
element = element + 1
end
else do
start_pars = 1
/********************************************************************/
/* */
/* The following code loops through the install statement and */
/* puts the product names in the product queue. */
/* */
/********************************************************************/
do until separator = last_plus
separator = pos('+',client_data,start_pars)
queue.queue_cnt.element =,
substr(client_data,start_pars,,
separator-start_pars)
start_pars = separator
start_pars = start_pars + 1
element = element + 1
end
/********************************************************************/
/* */
/* Save the last product name from the previous loop. */
/* */
/********************************************************************/
queue.queue_cnt.element =,
substr(client_data,start_pars)
element = element + 1
call bump_inc
end
end
end
/********************************************************************/
/* */
/* The following code handles an install statement that has only */
/* one product in it. */
/* */
/********************************************************************/
when lastpos('+', strip(client_cmd.data.client_i)) = 0,
then do
nextline = client_i + 1
if substr(strip(client_cmd.data.nextline),1,1) = "+"
then do
queue.queue_cnt.element = client_cmd.data.client_i
call bump_inc
element = element + 1
end
else do
queue.queue_cnt.element = client_cmd.data.client_i
call bump_inc
queue_cnt = queue_cnt + 1
element = 1
NOPLUS = TRUE
end
end
/********************************************************************/
/* */
/* The following code handles an install statement that a plus at */
/* the beginning of it. */
/* */
/********************************************************************/
when pos('+', strip(client_cmd.data.client_i)) = 1,
then do
client_data = strip(strip(client_cmd.data.client_i),'L','+')
/********************************************************************/
/* */
/* If there was only one plus then store the product name and */
/* go to the next line. */
/* */
/********************************************************************/
last_plus = lastpos('+', client_data)
if last_plus = 0 then do
queue.queue_cnt.element = client_data
call bump_inc
element = element + 1
end
else do
/********************************************************************/
/* */
/* Loop through the install statement and store the product names */
/* in the queue. */
/* */
/********************************************************************/
start_pars = 1
do until separator = last_plus
separator = pos('+',client_data,start_pars)
queue.queue_cnt.element =,
substr(client_data,start_pars,,
separator-start_pars)
start_pars = separator
start_pars = start_pars + 1
element = element + 1
end
/********************************************************************/
/* */
/* Store the last name from the previous loop. */
/* */
/********************************************************************/
queue.queue_cnt.element =,
substr(client_data,start_pars)
nextline = client_i + 1
if substr(strip(client_cmd.data.nextline),1,1) = "+"
then do
call bump_inc
element = element + 1
end
else do
call bump_inc
queue_cnt = queue_cnt + 1
element = 1
NOPLUS = TRUE
end
end
end
/********************************************************************/
/* */
/* The following code handles a statement that does not have a + at */
/* either end of an install statement. */
/* */
/********************************************************************/
otherwise do
last_plus = lastpos('+', client_cmd.data.client_i)
start_pars = 1
/********************************************************************/
/* */
/* Loop through the install statement and store the product names */
/* in the queue. */
/* */
/********************************************************************/
do until separator = last_plus
separator = ,
pos('+',client_cmd.data.client_i,start_pars)
queue.queue_cnt.element =,
substr(client_cmd.data.client_i,start_pars,,
separator-start_pars)
start_pars = separator
start_pars = start_pars + 1
element = element + 1
end
/********************************************************************/
/* */
/* Store last product in queue element. Increment to the next line */
/* to be read from the inout file, bump the queue count, and reset */
/* the element count to 1. */
/* */
/********************************************************************/
queue.queue_cnt.element =,
substr(client_cmd.data.client_i,start_pars)
call bump_inc
queue_cnt = queue_cnt + 1
element = 1
if substr(strip(client_cmd.data.client_i),1) = '+' &,
length(strip(client_cmd.data.client_i)) = 1
then call bump_inc
else NOPLUS = TRUE
end
end
end
end /* do until */
end /* end select */
end /* end for do while <> ENDINSTALL */
end /* end for if KEYWORDS install */
else do
/********************************************************************/
/* */
/* Process :INSTALL (no keywords) */
/* */
/* Process until :ENDINSTALL is found. The Invoke keyword may span */
/* more than one line so each line is stored in a separate element */
/* of the invoke array. "invoke_cnt" is the count of the invoke */
/* array. Each element in the array has the leading and trailing */
/* blanks removed and has the quotes changed from denoting the */
/* variable (input file form) to denoting the string (REXX form). */
/* */
/********************************************************************/
call bump_inc
do while translate(client_cmd.data.client_i) <> ":ENDINSTALL"
select
when translate(client_cmd.data.client_i) = ""
then do
call bump_inc
end
Otherwise do
invoke_cnt = 1
/********************************************************************/
/* */
/* If this line does not have a + or a ++ at the end of the line */
/* and the next line is not :ENDINSTALL then the invoke command */
/* spans more than one line, process the invoke command until a +, */
/* ++, or endinstall is found. */
/* */
/********************************************************************/
do until pos('++',client_cmd.data.prevline) <> 0 |,
translate(strip(client_cmd.data.client_i)),
= ":ENDINSTALL"
select
/********************************************************************/
/* */
/* If this line is a USERLINE then add the line to the queue. If */
/* the next line is a plus it belongs to this queue so increment */
/* the element count and bump to the next line. If the next is a ++ */
/* then it is to be in a queue by itself. Increment to the */
/* next queue and reset the element count to 1. */
/* */
/********************************************************************/
when translate(substr(strip(client_cmd.data.client_i),1,8)),
= "USERLINE" then do
queue.queue_cnt.element = client_cmd.data.client_i
nextline = client_i + 1
if pos('+', client_cmd.data.nextline) = 0 |,
pos('++',client_cmd.data.nextline) <> 0
then do
queue_cnt= queue_cnt + 1
element = 1
end
else element = element + 1
call bump_inc
end
/********************************************************************/
/* */
/* If this line is a SRVATTCH then add the line to the queue. If */
/* the next line is a plus it belongs to this queue so increment */
/* the element count and bump to the next line. If the next is a ++ */
/* then it is to be in a queue by itself. Increment to the */
/* next queue and reset the element count to 1. */
/* */
/********************************************************************/
when translate(substr(strip(client_cmd.data.client_i),1,8)),
= "SRVATTCH" then do
queue.queue_cnt.element = client_cmd.data.client_i
nextline = client_i + 1
if pos('+', client_cmd.data.nextline) = 0 |,
pos('++',client_cmd.data.nextline) <> 0
then do
queue_cnt= queue_cnt + 1
element = 1
end
else element = element + 1
call bump_inc
end
/********************************************************************/
/* */
/* When only a + on the line go to the next in the CMD file. */
/* */
/********************************************************************/
when length(strip(client_cmd.data.client_i))= 1 &,
pos('+', client_cmd.data.nextline) <> 0
then call bump_inc
/********************************************************************/
/* */
/* When only a ++ on the line go to the next in the CMD file. */
/* */
/********************************************************************/
when length(strip(client_cmd.data.client_i))= 2 &,
pos('++', client_cmd.data.nextline) <> 0
then call bump_inc
/********************************************************************/
/* */
/* The following code is to handle the invoke statement. */
/* */
/********************************************************************/
otherwise
do until pos('+',client_cmd.data.client_i) <> 0 |,
pos('++',client_cmd.data.client_i) <> 0 |,
translate(strip(client_cmd.data.client_i)),
= ":ENDINSTALL"
select
/********************************************************************/
/* */
/* if the line is blank then go to the next line in the CMD file. */
/* */
/********************************************************************/
when translate(client_cmd.data.client_i) = ""
then call bump_inc
/********************************************************************/
/* */
/* Strip off the trailing + and any blanks, then store away this */
/* line of the invoke statement. */
/* */
/********************************************************************/
otherwise
product.prod_cnt.invoke.invoke_cnt =,
strip(client_cmd.data.client_i,'t','+')
product.prod_cnt.invoke.invoke_cnt =,
strip(product.prod_cnt.invoke.invoke_cnt)
product.prod_cnt.invoke.invoke_cnt =,
fix_quotes(product.prod_cnt.invoke.invoke_cnt)
invoke_cnt = invoke_cnt + 1
call bump_inc
end
end
/********************************************************************/
/* */
/* If the next line is not an ENDINSTALL store it away else */
/* decrement the line count so we find the ENDINSTALL on the do */
/* loop */
/* */
/********************************************************************/
if translate(strip(client_cmd.data.client_i)),
<> ":ENDINSTALL"
then do
product.prod_cnt.invoke.invoke_cnt =,
strip(client_cmd.data.client_i,'t','+')
product.prod_cnt.invoke.invoke_cnt =,
strip(product.prod_cnt.invoke.invoke_cnt)
product.prod_cnt.invoke.invoke_cnt =,
fix_quotes(product.prod_cnt.invoke.invoke_cnt)
end
else do
client_i = client_i - 1
end
/********************************************************************/
/* */
/* Parse out the name from the invoke string. The name will be */
/* between the last "/" and the first " " (blank). */
/* */
/********************************************************************/
first_parm = pos(' ',product.prod_cnt.invoke.1)
instprog = strip(substr(product.prod_cnt.invoke.1,1,first_parm - 1))
start_prog = lastpos('\',instprog)
prod_name = strip(substr(instprog,start_prog + 1))
/********************************************************************/
/* */
/* If a product is to be invoked more than once each invocation */
/* must have a unique name. To make it unique a number is */
/* concatenated to the name. Check to see if the name is unique. If */
/* it is store it away. If not increment the concatentaion number */
/* by 1, see if it has been used. If it has not been used */
/* concatenate it and store it away. */
/* */
/********************************************************************/
if symbol('names.prod_name') = 'LIT'
then do
names.prod_name = prod_name
user_name = prod_name
end
else do
name_inc = 1
new_name = prod_name
do until symbol('names.new_name') = 'LIT'
new_name = prod_name||name_inc
name_inc = name_inc + 1
end
user_name = new_name
names.new_name = new_name
prod_name = new_name
end
/********************************************************************/
/* */
/* If this line ends in ++ or the next line is :ENDINSTALL then */
/* this is the end of the queue, say so by setting end_queue = yes. */
/* Store away the product information and bump the counters. */
/* Continue processing products for this queue. */
/* */
/********************************************************************/
queue.queue_cnt.element = prod_name
product.prod_cnt.prog_name = prod_name
product.prod_cnt.name = user_name
element = element + 1
prod_cnt = prod_cnt + 1
invoke_cnt = 1
prevline = client_i
call bump_inc
end /* select */
end /* end plusplus */
/********************************************************************/
/* */
/* Came to the end of the products for this queue. Reset counters */
/* and process the next queue if there is one. */
/* */
/********************************************************************/
queue_cnt = queue_cnt + 1
element = 1
end /* end otherwise */
end /* end select */
end /* end do while */
end /* end else do for non keyword install */
end /* end then for INSTALL keyword */
/********************************************************************/
/* */
/* If this line is blank skip over it. */
/* */
/********************************************************************/
when client_cmd.data.client_i = '' then NOP
otherwise
/********************************************************************/
/* */
/* If the keyword is invalid tell the user. */
/* */
/********************************************************************/
say "Error - Found invalid :KEYWORD ("keyword") line number " client_i
return (1)
end /* end select */
end /* end if */
end /* end do while */
/********************************************************************/
/* */
/* The input file has been processed. Now we build the output file. */
/* Read the bas file and store the lines from it into the output */
/* file. */
/* */
/********************************************************************/
castle_i = 1
do base_i = 1 to base_cmd.data.0
comment = substr(base_cmd.data.base_i,3,30)
select
/********************************************************************/
/* */
/* Combined with system data, not used. */
/* */
/********************************************************************/
when translate(comment) = 'START VARS HERE'
then do
var_cnt = 1
castle_cmd.data.castle_i = base_cmd.data.base_i
castle_i = castle_i + 1
castle_cmd.data.castle_i = ''
castle_i = castle_i + 1
end
/********************************************************************/
/* */
/* Insert the SRVATTCHes into the output file. Keep processing the */
/* srvattch array until a literal is found which means the end of */
/* the array. */
/* */
/********************************************************************/
when translate(comment) = 'START SRVATTACHES HERE'
then do
srvatt_cnt = 1
castle_cmd.data.castle_i = base_cmd.data.base_i
castle_i = castle_i + 1
castle_cmd.data.castle_i = ''
castle_i = castle_i + 1
do while symbol('srvattch.srvatt_cnt') <> 'LIT'
castle_cmd.data.castle_i = '"SRVATTCH"' srvattch.srvatt_cnt
castle_i = castle_i + 1
srvatt_cnt = srvatt_cnt + 1
end
end
/********************************************************************/
/* */
/* Insert the variables into the output file. Keep processing the */
/* variable array until a literal is found which means the end of */
/* the array. */
/* */
/********************************************************************/
when translate(comment) = 'START SYSTEM DATA HERE'
then do
var_cnt = 1
castle_cmd.data.castle_i = base_cmd.data.base_i
castle_i = castle_i + 1
castle_cmd.data.castle_i = ''
castle_i = castle_i + 1
do while symbol('vars.var_cnt') <> 'LIT'
castle_cmd.data.castle_i = vars.var_cnt
castle_i = castle_i + 1
var_cnt = var_cnt + 1
end
end
/********************************************************************/
/* */
/* Insert the product data into the output file. Keep processing */
/* the data for each product until the name for a product is a */
/* literal. This indicates the end of the product array. */
/* */
/********************************************************************/
when translate(comment) = 'START PRODUCT DATA HERE'
then do
castle_cmd.data.castle_i = base_cmd.data.base_i
castle_i = castle_i + 1
castle_cmd.data.castle_i = ''
castle_i = castle_i + 1
prod_cnt = 1
util_cnt = 1
do until symbol('product.prod_cnt.name') = 'LIT'
/********************************************************************/
/* */
/* Assign a product number to the product name. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."product.prod_cnt.prog_name" = ",
prod_cnt
castle_i = castle_i + 1
/********************************************************************/
/* */
/* Store the product name. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."prod_cnt".name = ",
'"'product.prod_cnt.name'"'
castle_i = castle_i + 1
/********************************************************************/
/* */
/* assign the state variable for this product and add it to the */
/* output file. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."prod_cnt".statevar = ""CAS_""",
"|| x."||prod_cnt||".name"
castle_i = castle_i + 1
/********************************************************************/
/* */
/* Store the product install command and all of its parameters. */
/* Keep reading the parameters from the invoke array until a */
/* literal is returned. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."prod_cnt".instprog = ",
product.prod_cnt.invoke.1","
castle_i = castle_i + 1
invoke_cnt = 2
do while symbol('product.prod_cnt.invoke.invoke_cnt') <> 'LIT'
castle_cmd.data.castle_i = ' 'product.prod_cnt.invoke.invoke_cnt','
castle_i = castle_i + 1
invoke_cnt = invoke_cnt + 1
end
castle_i = castle_i - 1
castle_cmd.data.castle_i = strip(castle_cmd.data.castle_i,'t',',')
castle_i = castle_i + 1
/********************************************************************/
/* */
/* Store the path to the response file for this product. If one is */
/* not found store a blank for the path. */
/* */
/********************************************************************/
if symbol('product.prod_cnt.rspdir') <> LIT
then do
castle_cmd.data.castle_i = "x."prod_cnt".rspdir = ",
product.prod_cnt.rspdir
castle_i = castle_i + 1
end
else do
castle_cmd.data.castle_i = "x."prod_cnt".rspdir = """""
castle_i = castle_i + 1
end
/********************************************************************/
/* */
/* Store the default response file name for this product. If one is */
/* not found store a blank for the path. */
/* */
/********************************************************************/
if symbol('product.prod_cnt.default') <> LIT
then do
castle_cmd.data.castle_i = "x."prod_cnt".default = ",
product.prod_cnt.default
castle_i = castle_i + 1
end
else do
castle_cmd.data.castle_i = "x."prod_cnt".default = """""
castle_i = castle_i + 1
end
/********************************************************************/
/* */
/* Bump the counters and go to the next product. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = ''
castle_i = castle_i + 1
prod_cnt = prod_cnt + 1
end
/********************************************************************/
/* */
/* Insert the utility data into the output file. Keep processing */
/* the data for each utility until the name for a utility is a */
/* literal. This indicates the end of the utility array. */
/* */
/********************************************************************/
do while symbol('utility.util_cnt.name') <> 'LIT'
/********************************************************************/
/* */
/* Assign a product number to the utility name. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."utility.util_cnt.util_name" = ",
prod_cnt
castle_i = castle_i + 1
/********************************************************************/
/* */
/* Store the utility name. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."prod_cnt".name = ",
'"'utility.util_cnt.name'"'
castle_i = castle_i + 1
/********************************************************************/
/* */
/* assign the state variable for this utility and add it to the */
/* output file. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."prod_cnt".statevar = """""
castle_i = castle_i + 1
/********************************************************************/
/* */
/* Store the utility install command and all of its parameters. */
/* Keep reading the parameters from the invoke array until a */
/* literal is returned. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = "x."prod_cnt".instprog = ",
utility.util_cnt.invoke.1","
castle_i = castle_i + 1
invoke_cnt = 2
do while symbol('utility.util_cnt.invoke.invoke_cnt') <> 'LIT'
castle_cmd.data.castle_i = ' 'utility.util_cnt.invoke.invoke_cnt','
castle_i = castle_i + 1
invoke_cnt = invoke_cnt + 1
end
castle_i = castle_i - 1
castle_cmd.data.castle_i = strip(castle_cmd.data.castle_i,'t',',')
castle_i = castle_i + 1
/********************************************************************/
/* */
/* Store the path to the response file for this utility. If one is */
/* not found store a blank for the path. */
/* */
/********************************************************************/
if symbol('utility.util_cnt.rspdir') <> LIT
then do
castle_cmd.data.castle_i = "x."prod_cnt".rspdir = ",
utility.util_cnt.rspdir
castle_i = castle_i + 1
end
else do
castle_cmd.data.castle_i = "x."prod_cnt".rspdir = """""
castle_i = castle_i + 1
end
/********************************************************************/
/* */
/* Store the default response file name for this utility. If one is */
/* not found store a blank for the path. */
/* */
/********************************************************************/
if symbol('utility.util_cnt.default') <> LIT
then do
castle_cmd.data.castle_i = "x."prod_cnt".default = ",
utility.util_cnt.default
castle_i = castle_i + 1
end
else do
castle_cmd.data.castle_i = "x."prod_cnt".default = """""
castle_i = castle_i + 1
end
castle_cmd.data.castle_i = ''
/********************************************************************/
/* */
/* Bump the counters and go to the next product. */
/* Prod_cnt used as index into product/utility array. */
/* */
/********************************************************************/
castle_i = castle_i + 1
prod_cnt = prod_cnt + 1
util_cnt = util_cnt + 1
end
/********************************************************************/
/* */
/* Store total number of products and utilities. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = 'NUM_INSTALL_PROGS = 'prod_cnt-1
castle_i = castle_i + 1
end
/********************************************************************/
/* */
/* Create the install sequence. */
/* */
/********************************************************************/
when translate(comment) = 'PUT INSTALLS HERE'
then do
/********************************************************************/
/* */
/* Start with the first element in the first queue and set the */
/* overall state to 0. */
/* */
/********************************************************************/
queue_cnt = 1
element = 1
overall_state = 0
/********************************************************************/
/* */
/* Keep processing until the queue element is a literal. */
/* */
/********************************************************************/
do until symbol('queue.queue_cnt.element') = 'LIT'
/********************************************************************/
/* */
/* This queue is an install sequence. */
/* Create the "When OVERALL_STATE for this queue sequence. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = ' when OVERALL_STATE = 'overall_state,
'then do'
castle_i = castle_i + 1
do until symbol('queue.queue_cnt.element') = 'LIT'
if translate(queue.queue_cnt.element) = "SEMAINT" then do
castle_cmd.data.castle_i = ,
' if BootDriveIsDiskette() == YES then iterate'
castle_i = castle_i + 1
end
element = element + 1
end
element = 1
/********************************************************************/
/* */
/* Create the RunInstall statements for each product in this queue. */
/* */
/********************************************************************/
do until symbol('queue.queue_cnt.element') = 'LIT'
select
when translate(substr(queue.queue_cnt.element,1,8)) = "SRVATTCH"
then do
castle_cmd.data.castle_i = ' 'substr(queue.queue_cnt.element,10)
castle_i = castle_i + 1
element = element + 1
end
when translate(substr(queue.queue_cnt.element,1,8)) = "USERLINE"
then do
castle_cmd.data.castle_i = ' 'substr(queue.queue_cnt.element,10)
castle_i = castle_i + 1
element = element + 1
end
/* when translate(queue.queue_cnt.element) = "SEMAINT"
then do
castle_cmd.data.castle_i = ,
' if BootDriveIsDiskette() == YES then iterate'
castle_i = castle_i + 1
castle_cmd.data.castle_i = ' if RunInstall(x.',
||queue.queue_cnt.element') == BAD_RC then exit'
castle_i = castle_i + 1
element = element + 1
end */
otherwise do
castle_cmd.data.castle_i = ' if RunInstall(x.',
||queue.queue_cnt.element') == BAD_RC then exit'
castle_i = castle_i + 1
element = element + 1
end
end
end
/********************************************************************/
/* */
/* Bump to the next queue and reset the element to 1. */
/* */
/********************************************************************/
queue_cnt = Queue_cnt + 1
element = 1
/********************************************************************/
/* */
/* If this is the last queue sequence then call Reboot, else call */
/* CheckBoot. CheckBoot will check to see if any product installs */
/* requested a reboot before rebooting. Reboot will do an */
/* unconditional reboot. */
/* */
/********************************************************************/
if symbol('queue.queue_cnt.element') = 'LIT'
then castle_cmd.data.castle_i = ' Call Reboot'
else castle_cmd.data.castle_i = ' Call CheckBoot'
/********************************************************************/
/* */
/* End the When statement and bump the OVERALL_STATE */
/* */
/********************************************************************/
castle_i = castle_i + 1
castle_cmd.data.castle_i = ' end'
castle_i = castle_i + 1
overall_state = overall_state + 1
end
end
Otherwise
/********************************************************************/
/* */
/* If there was nothing for CASPREP to do with this line then just */
/* copy it from the base to the output file. */
/* */
/********************************************************************/
castle_cmd.data.castle_i = base_cmd.data.base_i
castle_i = castle_i + 1
end
end
/********************************************************************/
/* */
/* Remember the length of the output file. */
/* */
/********************************************************************/
castle_cmd.data.0 = castle_i-1
/************************************************************************/
/* */
/* Erase the old output file and write the new one to disk. */
/* */
/************************************************************************/
outputfile = outfn||'.'||outfext
if stream(outputfile,'c','query exists') <> '' then do
'@echo off'
say 'Erasing existing' outputfile
"ERASE" outputfile
'@echo on'
end
say "Creating output file " outfn||'.'||outfext
do line_ctr = 1 to castle_cmd.data.0
rc = lineout(outputfile,castle_cmd.data.line_ctr)
end
/*lineout(outputfile) */
return (0)
exit (0)
/************************************************************************/
/************************************************************************/
/** **/
/** Internal Procedures **/
/** **/
/************************************************************************/
/************************************************************************/
/********************************************************************/
/* */
/* The fix_quotes procedure will modify a line to change the quotes */
/* from denoting the variable (input file format) to denoting a */
/* string (REXX format). It also looks for a mismatched quote. If */
/* a unmatched quote is found. CASPREP will display a message with */
/* the line and stop processing. Both the (') and the (") quotes */
/* will be looked for. The 2 quote types can be mixed on a single */
/* line. */
/* */
/********************************************************************/
fix_quotes: procedure EXPOSE client_i
quote_cnt = 0
charpos = 0
fix_string = arg(1)
/************************************************************************/
/* */
/* Find all of the (") quotes. */
/* */
/************************************************************************/
if pos('"',fix_string) <> 0
then do
do until charpos = lastpos('"',fix_string)
charpos = pos('"',fix_string,charpos+1)
quote_cnt = quote_cnt + 1
end
end
charpos = 0
/************************************************************************/
/* */
/* Find all of the (') quotes. */
/* */
/************************************************************************/
if pos("'",fix_string) <> 0
then do
do until charpos = lastpos("'",fix_string)
charpos = pos("'",fix_string,charpos+1)
quote_cnt = quote_cnt + 1
end
end
/************************************************************************/
/* */
/* Check for odd number of quotes. */
/* */
/* Quote_cnt is converted to hex and ORed with 'fffe'x to see if the */
/* low order bit is on (odd). */
/* */
/************************************************************************/
if quote_cnt <> 0
then do
quote_len = length(quote_cnt)
quote_cnt = substr(quote_cnt,quote_len,1)
quote_cnt = c2x(quote_cnt)
/************************************************************************/
/* */
/* If the count is odd then display an error message with the line. */
/* */
/************************************************************************/
if bitor('fffe'x,quote_cnt) = 'ffff'x
then do
say "Line number " client_i "has a mismatched quote. Processing has"
say "stopped."
say fix_string
exit (1)
end
end
/************************************************************************/
/* */
/* If the first character in the string is a quote then remove it. */
/* If the first character in the string is not a quote then add one. */
/* If the last character in the string is a quote then remove it. */
/* If the last character in the string is not a quote then add one. */
/* */
/* Check for either type quote. */
/* */
/************************************************************************/
if substr(fix_string,1,1) = '"' |,
substr(fix_string,1,1) = ''''
then do
fix_string = strip(fix_string,'l','"')
fix_string = strip(fix_string,'l',"'")
end
else do
fix_string = """"||fix_string
end
str_len = length(fix_string)
if substr(fix_string,str_len,1) = '"' |,
substr(fix_string,str_len,1) = ''''
then do
fix_string = strip(fix_string,'t','"')
fix_string = strip(fix_string,'t','''')
quotes = yes
end
else do
fix_string = fix_string||""""
end
return(fix_string)
/************************************************************************/
/* */
/* The remove_comments procedure will remove the comments from the */
/* input string. */
/* */
/************************************************************************/
remove_comments: procedure expose client_cmd. client_i
newstr = arg(1)
do while newstr = '' & client_i <> client_cmd.data.0
client_i = client_i + 1
newstr = client_cmd.data.client_i
end
do while pos('/*',newstr) <> 0
newstr = strip(newstr)
str_len = length(newstr)
start_com = pos('/*',newstr)
end_com = pos('*/',newstr)
select
/************************************************************************/
/* */
/* If the whole line is a comment then get next line. */
/* */
/************************************************************************/
when start_com = 1 & end_com = str_len-1
then do
client_i = client_i + 1
newstr = client_cmd.data.client_i
end
/************************************************************************/
/* */
/* If only start of comment in this line look for end of comment */
/* */
/************************************************************************/
when start_com = 1 & end_com = 0
then do
do until pos('*/', newstr) <> 0
client_i = client_i + 1
newstr = client_cmd.data.client_i
end
client_i = client_i + 1
newstr = client_cmd.data.client_i
end
otherwise do
if start_com <> 1 then newstr = strip(substr(newstr,1,start_com-1))
else newstr = strip(substr(newstr,end_com+2))
end
end
do while newstr = '' & client_i <> client_cmd.data.0
client_i = client_i + 1
newstr = client_cmd.data.client_i
end
end
return newstr
/************************************************************************/
/* */
/* The bump_inc procedure increments the index into the input file and */
/* removes the comments from that line. */
/* */
/************************************************************************/
bump_inc: procedure expose client_cmd. client_i
client_i = client_i + 1
client_cmd.data.client_i = remove_comments(client_cmd.data.client_i)
return
/************************************************************************/
/* */
/* The help procedure displays the command syntax when called */
/* */
/************************************************************************/
find_keyword: procedure expose client_cmd. client_i
keyword_fnd = 0
if pos('NAME', translate(strip(client_cmd.data.client_i))) <> 0 then
keyword_fnd = 1
if pos('RSPDIR', translate(strip(client_cmd.data.client_i))) <> 0 then
keyword_fnd = 1
if pos('DEFAULT', translate(strip(client_cmd.data.client_i))) <> 0 then
keyword_fnd = 1
return keyword_fnd
/************************************************************************/
/* */
/* The help procedure displays the command syntax when called */
/* */
/************************************************************************/
help: procedure
say "The CASPREP command syntax is"
say "input file output file (base file)"
say ""
say "The base file name is optional."
return